using System.Collections.Generic;
using ProtoModels;
using UnityEngine;

public class PlayerStats : SkillProvider
{
	public delegate void OnSave();

	private OnSave onSave;

	private PlayerModel model;

	public PlayerStats(PlayerModel model, OnSave onSave, SkillConfig skillConfig)
	{
		this.model = model;
		this.onSave = onSave;
		base.skillConfig = skillConfig;
	}

	public List<SkillLevel> GetOriginalSkillsList()
	{
		List<int> list = new List<int>();
		list.Add(0);
		list.Add(1);
		List<SkillLevel> list2 = new List<SkillLevel>();
		if (model != null && model.skills != null)
		{
			foreach (SkillLevel skill in model.skills)
			{
				if (list.IndexOf(skill.skillTypeInt) >= 0)
				{
					list2.Add(skill);
				}
			}
		}
		return list2;
	}

	public void ReloadModel(PlayerModel model)
	{
		this.model = model;
	}

	public override float DoGetSkillValue(int skillTypeIndex)
	{
		return GetProjectedSkillValue(skillTypeIndex, 0f);
	}

	public LevelSystem.LevelInfo GetLevelInfo(int skillTypeIndex)
	{
		SkillLevel orAddSkill = GetOrAddSkill(model.skills, skillTypeIndex);
		return LevelSystem.instance.GetSkillLevelInfo((PlayerStatsManager.SkillType)skillTypeIndex, orAddSkill.level);
	}

	public float GetProjectedSkillValue(int skillTypeIndex, float xpToAdd)
	{
		if (model.skills == null)
		{
			model.skills = new List<SkillLevel>();
		}
		switch (skillTypeIndex)
		{
		case 3:
		{
			StoreItemsConfig.StoreItem usedItem2 = StoreItemsConfig.instance.GetUsedItem(StoreItemsConfig.StoreItem.ItemType.Shoe);
			return usedItem2.NormalizedVisualSpeed();
		}
		case 2:
		{
			StoreItemsConfig.StoreItem usedItem = StoreItemsConfig.instance.GetUsedItem(StoreItemsConfig.StoreItem.ItemType.Racket);
			Debug.Log("Racket visual speed " + usedItem.NormalizedVisualSpeed());
			return usedItem.NormalizedVisualSpeed();
		}
		default:
		{
			SkillLevel orAddSkill = GetOrAddSkill(model.skills, skillTypeIndex);
			LevelSystem.LevelInfo skillLevelInfo = LevelSystem.instance.GetSkillLevelInfo((PlayerStatsManager.SkillType)skillTypeIndex, orAddSkill.level + xpToAdd);
			return (float)skillLevelInfo.levelIndex + skillLevelInfo.subLevelProgress;
		}
		}
	}

	private SkillLevel GetOrAddSkill(List<SkillLevel> skills, int skillTypeIndex)
	{
		foreach (SkillLevel skill in skills)
		{
			if (skill.skillTypeInt == skillTypeIndex)
			{
				return skill;
			}
		}
		SkillLevel skillLevel = new SkillLevel();
		skillLevel.skillTypeInt = skillTypeIndex;
		skillLevel.level = 0f;
		skills.Add(skillLevel);
		DoOnSave();
		return skillLevel;
	}

	private void DoOnSave()
	{
		if (onSave != null)
		{
			onSave();
		}
	}

	public float GetAttributeValue(int attrTypeIndex)
	{
		if (model.attributes == null)
		{
			model.attributes = new List<SkillLevel>();
		}
		SkillLevel orAddSkill = GetOrAddSkill(model.attributes, attrTypeIndex);
		return (float)LevelSystem.instance.GetAttributeValue((PlayerStatsManager.AttributeType)attrTypeIndex, orAddSkill.level) + GetAttributeProgress(attrTypeIndex);
	}

	public float GetProjectedAttributeValue(int attrTypeIndex, float xpToAdd = 0f)
	{
		if (model.attributes == null)
		{
			model.attributes = new List<SkillLevel>();
		}
		SkillLevel orAddSkill = GetOrAddSkill(model.attributes, attrTypeIndex);
		return (float)LevelSystem.instance.GetAttributeValue((PlayerStatsManager.AttributeType)attrTypeIndex, orAddSkill.level + xpToAdd) + GetAttributeProgress(attrTypeIndex, xpToAdd);
	}

	public float GetAttributeProgress(int attrTypeIndex, float xpToAdd = 0f)
	{
		if (model.attributes == null)
		{
			model.attributes = new List<SkillLevel>();
		}
		SkillLevel orAddSkill = GetOrAddSkill(model.attributes, attrTypeIndex);
		int attributeValue = LevelSystem.instance.GetAttributeValue((PlayerStatsManager.AttributeType)attrTypeIndex, orAddSkill.level + xpToAdd);
		int attrPointsValForLevel = LevelSystem.instance.GetAttrPointsValForLevel((PlayerStatsManager.AttributeType)attrTypeIndex, attributeValue);
		int attrPointsValForLevel2 = LevelSystem.instance.GetAttrPointsValForLevel((PlayerStatsManager.AttributeType)attrTypeIndex, attributeValue + 1);
		return Mathf.Clamp((orAddSkill.level + xpToAdd - (float)attrPointsValForLevel) / (float)(attrPointsValForLevel2 - attrPointsValForLevel), 0f, 1f);
	}

	public void UpdateSkill(float skillChange, int skillTypeIndex)
	{
		if (model.skills == null)
		{
			model.skills = new List<SkillLevel>();
		}
		GetOrAddSkill(model.skills, skillTypeIndex).level += skillChange;
		DoOnSave();
	}

	public void UpdateAttribute(float attributeChange, int attrTypeIndex)
	{
		if (model.attributes == null)
		{
			model.attributes = new List<SkillLevel>();
		}
		GetOrAddSkill(model.attributes, attrTypeIndex).level += attributeChange;
		DoOnSave();
	}

	public void ResetAllStats()
	{
		if (model.attributes == null)
		{
			model.attributes = new List<SkillLevel>();
		}
		model.attributes.Clear();
		if (model.skills == null)
		{
			model.skills = new List<SkillLevel>();
		}
		model.skills.Clear();
		DoOnSave();
	}
}
